home *** CD-ROM | disk | FTP | other *** search
- /* IP-related user commands */
- #include <stdio.h>
- #include "global.h"
- #include "mbuf.h"
- #include "internet.h"
- #include "timer.h"
- #include "netuser.h"
- #include "iface.h"
- #include "ip.h"
- #include "cmdparse.h"
- #include "commands.h"
- #include "socket.h"
- #include "config.h"
-
- #ifdef IPACCESS
- static int doaccess __ARGS((int argc,char *argv[],void *p));
- #endif
- char RouteHeader[] = "Destination Len Interface Gateway Metric P Timer Use\n";
-
- /* Dump a routing table entry */
- int near
- dumproute(struct route *rp)
- {
- tprintf("%-16s%-4u",
- (rp->target != 0) ? inet_ntoa(rp->target) : "default",rp->bits);
- tprintf("%-13s%-17s",
- rp->iface->name,(rp->gateway != 0) ? inet_ntoa(rp->gateway) : "");
- tprintf("%-8lu%c %-7lu%lu\n",
- rp->metric,(rp->flags & RTPRIVATE) ? 'P' : ' ',
- read_timer(&rp->timer)/1000L,rp->uses);
- return;
- }
-
-
-
- /* ------------------------ IP subcmds ------------------------ */
-
- static int
- doipaddr(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- int32 n;
-
- if(argc < 2) {
- tprintf("%s\n",inet_ntoa(Ip_addr));
- } else if((n = resolve(argv[1])) == 0){
- tprintf(Badhost,argv[1]);
- return 1;
- } else
- Ip_addr = n;
- return 0;
- }
-
- static int
- dortimer(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- return setlong(&ipReasmTimeout,"IP reasm timeout (sec)",argc,argv);
- }
-
- static int
- doipstat(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct reasm *rp;
- struct frag *fp;
- int i;
-
- for(i = 1; i <= NUMIPMIB; i++){
- tprintf("(%2u)ip%-18s%10lu",
- i,Ip_mib[i].name,Ip_mib[i].value.integer);
- tputs((i % 2) ? " " : "\n");
- }
- if((i % 2) == 0)
- tputs("\n");
-
- if(Reasmq != NULLREASM) {
- tputs("Reassembly fragments:\n");
- for(rp = Reasmq; rp != NULLREASM; rp = rp->next){
- tprintf("src %s",inet_ntoa(rp->source));
- tprintf(" dest %s",inet_ntoa(rp->dest));
- tprintf(" id %u pctl %u time %lu len %u\n",
- rp->id,uchar(rp->protocol),read_timer(&rp->timer),rp->length);
- for(fp = rp->fraglist; fp != NULLFRAG; fp = fp->next)
- tprintf(" offset %u last %u\n",fp->offset,fp->last);
- }
- }
- return 0;
- }
-
- static int
- dottl(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- return setlong(&ipDefaultTTL,"IP TTL",argc,argv);
- }
-
- int
- doip(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- static struct cmds Ipcmds[] = {
- #ifdef IPACCESS
- "access", doaccess, 0, 0, NULLCHAR,
- #endif
- "address", doipaddr, 0, 0, NULLCHAR,
- "rtimer", dortimer, 0, 0, NULLCHAR,
- "status", doipstat, 0, 0, NULLCHAR,
- "ttl", dottl, 0, 0, NULLCHAR,
- NULLCHAR,
- };
- return subcmd(Ipcmds,argc,argv,p);
- }
-
-
- /* --------------------------- route subcmds ------------------------ */
-
- /* Add an entry to the routing table
- * E.g., "add 1.2.3.4 ax0 5.6.7.8 3"
- */
- static int
- doadd(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct iface *ifp;
- int32 dest,gateway;
- unsigned bits;
- char *bitp;
- int32 metric;
- char private;
-
- private = (strncmp(argv[0],"addp",4) == 0) ? 1 : 0;
-
- if(strcmp(argv[1],"default") == 0){
- bits = 0;
- dest = 0L;
- } else {
- /* If IP address is followed by an optional slash and
- * a length field, (e.g., 128.96/16) get it;
- * otherwise assume a full 32-bit address
- */
- if((bitp = strchr(argv[1],'/')) != NULLCHAR){
- /* Terminate address token for resolve() call */
- *bitp++ = '\0';
- bits = atoi(bitp);
- } else
- bits = 32;
-
- if((dest = resolve(argv[1])) == 0){
- tprintf(Badhost,argv[1]);
- return 1;
- }
- }
- if((ifp = if_lookup(argv[2])) == NULLIF){
- tprintf(Badif,argv[2]);
- return 1;
- }
- if(argc > 3){
- if((gateway = resolve(argv[3])) == 0){
- tprintf(Badhost,argv[3]);
- return 1;
- }
- } else {
- gateway = 0;
- }
- metric = (argc > 4) ? atol(argv[4]) : 1;
-
- if(rt_add(dest,bits,gateway,ifp,metric,0,private) == NULLROUTE)
- tputs("Can't add route\n");
- return 0;
- }
-
- /* Drop an entry from the routing table
- * E.g., "drop 128.96/16
- */
- static int
- dodrop(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- char *bitp;
- unsigned bits;
- int32 n;
-
- if(strcmp(argv[1],"default") == 0){
- n = 0;
- bits = 0;
- } else {
- /* If IP address is followed by an optional slash and length field,
- * (e.g., 128.96/16) get it; otherwise assume a full 32-bit address
- */
- if((bitp = strchr(argv[1],'/')) != NULLCHAR){
- *bitp++ = '\0';
- bits = atoi(bitp);
- } else
- bits = 32;
-
- if((n = resolve(argv[1])) == 0){
- tprintf(Badhost,argv[1]);
- return 1;
- }
- }
- return rt_drop(n,bits);
- }
-
- /* Force a timeout on all temporary routes */
- static int
- doflush(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct route *rp;
- struct route *rptmp;
- int i,j;
-
- if(R_default.timer.state == TIMER_RUN){
- rt_drop(0,0); /* Drop default route */
- }
- for(i = 0; i < HASHMOD; i++) {
- for(j=0;j<32;j++){
- for(rp = Routes[j][i];rp != NULLROUTE;rp = rptmp){
- rptmp = rp->next;
- if(rp->timer.state == TIMER_RUN){
- rt_drop(rp->target,rp->bits);
- }
- }
- }
- }
- return 0;
- }
-
- static int
- dolook(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct route *rp;
- int32 addr;
-
- if((addr = resolve(argv[1])) == 0) {
- tprintf(Badhost,argv[1]);
- return 1;
- }
- if((rp = rt_lookup(addr)) == NULLROUTE){
- tprintf("Host %s (%s) unreachable\n",argv[1],inet_ntoa(addr));
- return 1;
- }
- dumproute(rp);
- return 0;
- }
-
- /* Display and/or manipulate routing table */
- int
- doroute(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- int i, bits;
- struct route *rp;
-
- struct cmds Rtcmds[] = {
- "add", doadd, 0, 3,
- "route add <dest addr>[/<bits>] <iface> [gateway] [metric]",
-
- "addprivate", doadd, 0, 3,
- "route addprivate <dest addr>[/<bits>] <iface> [gateway] [metric]",
-
- "drop", dodrop, 0, 2,
- "route drop <dest addr>[/<bits>]",
-
- "flush", doflush, 0, 0,
- NULLCHAR,
-
- "lookup", dolook, 0, 2,
- "route lookup <dest addr>",
-
- NULLCHAR,
- };
-
- if(argc >= 2)
- return subcmd(Rtcmds,argc,argv,p);
-
- /* Dump IP routing table
- * Dest Len Interface Gateway Use
- * 192.001.002.003 32 sl0 192.002.003.004 0
- */
- tputs(RouteHeader);
-
- for(bits = 31; bits >= 0; bits--) {
- for(i = 0; i < HASHMOD; i++) {
- for(rp = Routes[bits][i];rp != NULLROUTE;rp = rp->next){
- if(dumproute(rp) == EOF)
- return 0;
- }
- }
- }
- if(R_default.iface != NULLIF)
- dumproute(&R_default);
-
- return 0;
- }
-
- #ifdef IPACCESS
- static int
- doaccess(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct iface *ifp;
- int32 source,target;
- unsigned sbits,tbits;
- char *bitp;
- int16 lport,hport,protocol,state;
- char *cp; /* for printing the table */
- struct rtaccess *tpacc;
- struct rtaccess *btacc;
- struct rtaccess *bfacc;
- struct rtaccess *head;
- char tmpbuf[15];
-
- if(argc == 1){ /* print out the table */
- tputs("Source Address Len Dest Address Len Interface Proto Low High State\n");
- for(tpacc = IPaccess;tpacc != NULLACCESS;tpacc = tpacc->nxtiface){
- for(btacc = tpacc;btacc != NULLACCESS;btacc = btacc->nxtbits){
- if(btacc->source != 0)
- cp = inet_ntoa(btacc->source);
- else
- cp = "all";
- tprintf("%-16s",cp);
- tprintf("%2u ",btacc->sbits);
- if(btacc->target != 0)
- cp = inet_ntoa(btacc->target);
- else
- cp = "all";
- tprintf("%-16s",cp);
- tprintf("%2u ",btacc->bits);
- tprintf("%-13s",btacc->iface->name);
- switch (btacc->protocol) {
- case 0:
- cp = "any";
- break;
- case ICMP_PTCL:
- cp = "icmp";
- break;
- case TCP_PTCL:
- cp = "tcp";
- break;
- case UDP_PTCL:
- cp = "udp";
- break;
- default:
- cp = itoa(btacc->protocol,tmpbuf,10);
- }
- tprintf("%-5s ",cp);
- tprintf("%5u ",btacc->lowport);
- tprintf("%5u ",btacc->highport);
- if(btacc->status)
- cp = "deny";
- else
- cp = "permit";
- tprintf("%-6s\n",cp);
- }
- }
- return 0;
- }
-
- if(strcmp(argv[1],"permit") == 0){
- state = 0;
- } else {
- if((strcmp(argv[1],"deny") == 0)
- || (strcmp(argv[1],"delete") == 0)){
- state = -1;
- } else {
- tputs("Format: ip access <permit|deny|delete> <proto> <src addr>[/<bits>] <dest addr>[/<bits>] <if name> [low [high]]\n");
- return 1;
- }
- }
-
- switch (*argv[2]){
- case 'a': /* ANY */
- protocol = 0;
- break;
- case 'i': /* ICMP */
- protocol = ICMP_PTCL;
- break;
- case 't': /* TCP */
- protocol = TCP_PTCL;
- break;
- case 'u': /* UDP */
- protocol = UDP_PTCL;
- break;
- default:
- protocol = atoi(argv[2]);
- }
-
- if(strcmp(argv[3],"all") == 0){
- source = 0;
- sbits = 0;
- } else {
- /* If IP address is followed by an optional slash and
- * a length field, (e.g., 128.96/16) get it;
- * otherwise assume a full 32-bit address
- */
- if((bitp = strchr(argv[3],'/')) != NULLCHAR){
- /* Terminate address token for resolve() call */
- *bitp++ = '\0';
- sbits = atoi(bitp);
- } else
- sbits = 32;
-
- if((source = resolve(argv[3])) == 0){
- tprintf(Badhost,argv[3]);
- return 1;
- }
- }
- if(strcmp(argv[4],"all") == 0){
- target = 0;
- tbits = 0;
- } else {
- if((bitp = strchr(argv[4],'/')) != NULLCHAR){
- *bitp++ = '\0';
- tbits = atoi(bitp);
- } else
- tbits = 32;
-
- if((target = resolve(argv[4])) == 0){
- tprintf(Badhost,argv[4]);
- return 1;
- }
- }
-
- if((ifp = if_lookup(argv[5])) == NULLIF){
- tprintf(Badif,argv[5]);
- return 1;
- }
-
- if(((protocol != TCP_PTCL) && (protocol != UDP_PTCL)) || (argc < 7)) {
- lport = 0;
- hport = 0;
- } else {
- if(strcmp(argv[6],"all") == 0){
- lport = 0;
- } else {
- lport = atoi(argv[6]);
- }
- if((argc < 8) || (lport == 0))
- hport = lport;
- else
- hport = atoi(argv[7]);
- }
-
- if(strcmp(argv[1],"delete") == 0){
- head = IPaccess;
- for(tpacc = IPaccess;tpacc != NULLACCESS;head = tpacc,tpacc = tpacc->nxtiface){
- if(tpacc->iface == ifp){
- for(btacc = tpacc;btacc != NULLACCESS;
- head = btacc,btacc = btacc->nxtbits){
- if((btacc->protocol == protocol) &&
- (btacc->source == source) &&
- (btacc->sbits == sbits) &&
- (btacc->target == target) &&
- (btacc->bits == tbits) &&
- (btacc->lowport == lport) &&
- (btacc->highport == hport)) { /*match*/
- bfacc = btacc; /* save to unalloc */
- /*now delete. watch for special cases*/
- if(btacc != tpacc){ /* not at head of list */
- head->nxtbits = btacc->nxtbits;
- free(bfacc);
- return 0;
- }
- if(btacc == IPaccess){ /* real special case */
- if(IPaccess->nxtbits == NULLACCESS)
- IPaccess = btacc->nxtiface;
- else {
- IPaccess = btacc->nxtbits;
- (btacc->nxtbits)->nxtiface = btacc->nxtiface;
- }
- } else { /* we know tpacc=btacc <> IPaccess */
- if(btacc->nxtbits == NULLACCESS)
- head->nxtiface = btacc->nxtiface;
- else {
- head->nxtiface = btacc->nxtbits;
- (btacc->nxtbits)->nxtiface = btacc->nxtiface;
- }
- }
- free(bfacc);
- return 0;
- }
- }
- }
- }
- tputs("Not found.\n");
- return 1;
- }
- /* add the access */
- addaccess(protocol,source,sbits,target,tbits,ifp,lport,hport,state);
- return 0;
- }
- #endif